import { defineStore } from 'pinia';
//引入路由(常量路由)
import { getRouter } from '@/router/router';
import { getToken, setToken, removeToken, type Token } from '@/utils/token';
import { reqLogin, reqUserInfo } from '@/utils/api/user';
import router from '@/router';
import type { UserState } from './types/type';
import type { RouteRecordRaw } from 'vue-router';
import type { LoginFormRequest, LoginFormResponse, IdentityUserDto } from '@/utils/api/user/type';
import {
  PermissionType,
  type PermissionTreeDto,
  type PermissionSet
} from '@/utils/api/permission/type';
import { reqPermissionCurr } from '@/utils/api/permission/index';
//引入深拷贝方法
import cloneDeep from 'lodash/cloneDeep';

// 获取权限
const getPermissions = async () => {
  const permissionTreeDto: Array<PermissionTreeDto> = await reqPermissionCurr();
  const permissions: PermissionSet = {
    module: new Set(),
    menu: new Set(),
    button: new Set()
  };
  const result = getSeletcPermission(permissionTreeDto, permissions);
  return result;
};
// 权限转化成数组
const getSeletcPermission = (
  permissions: Array<PermissionTreeDto>,
  data: PermissionSet
): PermissionSet => {
  permissions.forEach((item) => {
    if (item.type === PermissionType.Module) {
      data.module.add(item.name);
    } else if (item.type === PermissionType.Menu) {
      data.menu.add(item.name);
    } else if (item.type == PermissionType.Button) {
      data.button.add(item.name);
    }
    if (item.childPermissions && item.childPermissions.length > 0) {
      return getSeletcPermission(item.childPermissions, data);
    }
  });
  return data;
};
// 路由过滤
const filterRoute = (routeRecordRaw: RouteRecordRaw[], routes: string[]): RouteRecordRaw[] => {
  return routeRecordRaw.filter((item: RouteRecordRaw) => {
    if (item.meta) {
      const name = item.meta.permission as string;
      if (name && routes.includes(name)) {
        if (item.children && item.children.length > 0) {
          item.children = filterRoute(item.children, routes);
        }
        return true;
      }
    }
    return false;
  });
};
const useUserStore = defineStore('userStore', {
  state: (): UserState => {
    return {
      token: getToken(), //用户唯一标识token
      user: {
        id: '',
        userName: '',
        name: '',
        email: '',
        phoneNumber: '',
        emailConfirmed: false,
        phoneNumberConfirmed: false,
        isActive: false,
        lockoutEnabled: false,
        accessFailedCount: 0,
        isDeleted: false
      }, //用户基本信息
      menuRoutes: [],
      buttons: [],
      modules: []
    };
  },
  actions: {
    async userLogin(data: LoginFormRequest) {
      const result: LoginFormResponse = await reqLogin(data);
      const token: Token = {
        accessToken: result.accessToken,
        tokenType: result.tokenType,
        refreshToken: result.refreshToken,
        expiresIn: result.expiresIn
      };
      this.token = token;
      setToken(token);
    },
    async userInfo(id: string) {
      // 加载用户信息
      const result: IdentityUserDto = await reqUserInfo(id);
      this.user = result;
      // 加载权限信息
      const permissions = await getPermissions();
      this.modules = [...permissions.module];
      this.buttons = [...permissions.button];

      const { constantRoute, asyncRoute, anyRoute } = getRouter();

      //计算当前用户需要展示的异步路由
      const userAsyncRoute = filterRoute(cloneDeep(asyncRoute), [
        ...permissions.menu,
        'Panda.Net.Basic'
      ]);

      //菜单需要的数据整理完毕
      this.menuRoutes = [...constantRoute, ...userAsyncRoute, anyRoute];

      //目前路由器管理的只有常量路由:用户计算完毕异步路由、任意路由动态追加
      const dynamicRoute = [...userAsyncRoute, anyRoute];
      dynamicRoute.forEach((route: any) => {
        router.addRoute(route);
      });
    },
    userLogout() {
      const { constantRoute } = getRouter();
      this.user = null;
      this.token = null;
      this.menuRoutes = constantRoute;
      this.buttons = [];
      this.modules = [];
      removeToken();
    }
  },
  getters: {
    avatar: (state: UserState): string | undefined => {
      return state.user?.extraProperties?.Avatar;
    },
    name: (state: UserState): string | undefined => {
      return state.user?.name;
    },
    userData: (state: UserState): IdentityUserDto | null => {
      return state.user;
    },
    tokenData: (state: UserState): Token | null => {
      return state.token;
    },
    menuRouteData: (state: UserState): RouteRecordRaw[] | null => {
      return state.menuRoutes;
    },
    buttonData: (state: UserState): string[] | null => {
      return state.buttons;
    },
    moduleData: (state: UserState): string[] | null => {
      return state.modules;
    },
    getPaths: (state: UserState): string[] | null => {
      if(state.token && state.token.accessToken && state.user){
        return null;
      }
      return ['/canvas'];
    }
  }
});

export default useUserStore;
